#include "client.h"

// 与用户交互
int command_loop(int sock_fd) {
    // 用户输入缓冲区
    char buffer[MAX_INPUT_BUFFER] = { 0 };

    // 循环接收用户输入
    while (1) {
        printf("> ");
        fflush(stdout); // 确保提示符立即显示

        if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
            // 读取到文件末尾 (Ctrl+D) 或发生错误
            break;
        }

        // 移除 fgets 读取到的末尾换行符
        buffer[strcspn(buffer, "\n")] = 0;

        if (strlen(buffer) == 0) {
            continue; // 用户只敲了回车
        }

        if (strcmp(buffer, "quit") == 0 || strcmp(buffer, "exit") == 0) {
            break;
        }

        // 处理用户输入的命令
        handle_user_command(sock_fd, buffer);

    }
    return 0;
}

// 处理用户输入的命令
int handle_user_command(int sock_fd, char* command_line) {
    // 使用 strtok 分割命令和参数
    // 注意：strtok会修改原始字符串
    char* command = strtok(command_line, " ");
    char* argument = strtok(NULL, ""); // 获取剩余的所有部分作为参数

    if (command == NULL) return -1;

    if ((strcmp(command, "ls") == 0 && argument == NULL) || 
        (strcmp(command, "pwd") == 0 && argument == NULL)) {

        int type = (strcmp(command, "ls") == 0) ? CMD_LS : CMD_PWD;
        send_tlv(sock_fd, type, NULL, 0); // 这些命令没有参数
        receive_and_process_response(sock_fd);
   }
    else if (strcmp(command, "cd") == 0) {
        if (argument == NULL) {
            fprintf(stderr, "用法: cd <目录>\n");
            return -1;
        }
        send_tlv(sock_fd, CMD_CD, argument, strlen(argument));
        receive_and_process_response(sock_fd);
    }
    else if (strcmp(command, "gets") == 0) {
        if (argument == NULL) {
            fprintf(stderr, "用法: gets <远程文件名>\n");
            return -1;
        }

        char *path_copy = strdup(argument);
        if (path_copy == NULL) {
            perror("strdup failed");
            return -1;
        }

        // 从副本中提取纯净的文件名
        char *local_filename = basename(path_copy);
        // 下载逻辑
        send_tlv(sock_fd, CMD_GETS, argument, strlen(argument));
        // 调用文件接收函数，传入纯净的文件名
        receive_file_content(sock_fd, local_filename);
        free(path_copy);
    }
    else if (strcmp(command, "puts") == 0) {
        if (argument == NULL) {
            fprintf(stderr, "用法: puts <本地文件名>\n");
            return -1;
        }

        // 判断本地文件是否存在
        char *local_filename = argument;
        struct stat st;
        if (stat(local_filename, &st) != 0) {
            perror("本地文件不存在");
            return -1;
        }

        // 发送puts命令
        send_tlv(sock_fd, CMD_PUTS, local_filename, strlen(local_filename));
        // 等待服务端响应
        int server_response_type = wait_for_response_type(sock_fd);
        if (server_response_type != RESP_OK) {
            printf("服务器拒绝接收文件！\n");
            return -1;
        }
        printf("服务器已准备好，开始上传文件...\n");
        
        int fd = open(local_filename, O_RDONLY);
        ERROR_CHECK(fd, -1, "open local_filename failed");

        int bytes_read = 0;
        char buffer[4096] = { 0 };
        while ((bytes_read = read(fd, buffer, sizeof(buffer))) > 0) {
            send_tlv(sock_fd, RESP_FILE_DATA, buffer, bytes_read);
        }

        close(fd);

        // 发送结束标志（length为0的tlv数据包
        send_tlv(sock_fd, RESP_FILE_DATA, NULL, 0);

        printf("文件上传完毕，等待服务器最终确认...\n");
        receive_and_process_response(sock_fd);
        
    }
    else if (strcmp(command, "mkdir") == 0) {
        if (argument == NULL) {
            fprintf(stderr, "用法: mkdir <创建文件名>\n");
            return -1;
        }

        send_tlv(sock_fd, CMD_MKDIR, argument, strlen(argument));
        receive_and_process_response(sock_fd);
    }
    else if (strcmp(command, "rmdir") == 0) {
        if (argument == NULL) {
            fprintf(stderr, "用法: rmdir <删除文件名>\n");
            return -1;
        }

        send_tlv(sock_fd, CMD_RMKDIR, argument, strlen(argument));
        receive_and_process_response(sock_fd);
    }
    else if (strcmp(command, "remove") == 0) {
        if (argument == NULL) {
            fprintf(stderr, "用法: remove <远程文件名>\n");
            return -1;
        }
        send_tlv(sock_fd, CMD_REMOVE, argument, strlen(argument));
        receive_and_process_response(sock_fd);
    }
    else {
        fprintf(stderr, "无效命令: %s\n", command);
    }

    return 0;
}
